package com.baoyouqun.API.wxPay;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.cola.dto.SingleResponse;
import com.baoyouqun.domain.CreateCmd.OrderRecordCreateCmd;
import com.baoyouqun.domain.VO.OrderRecordVO;
import com.baoyouqun.service.OrderRecordService;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付控制器（小程序前端调用）
 */
@RestController
@RequestMapping("/api/pay/wx")
@Slf4j
@RequiredArgsConstructor
public class WechatPayController {


    private final WechatPayService wechatPayService;
    @Resource
    private OrderRecordService orderRecordService;

    /**
     * 1. 创建JSAPI支付订单（前端调起支付前调用）
     * 请求示例：POST /api/pay/wx/jsapi/create?orderId=PAY20240501001&payName=会员充值&price=99.00&openid=o6_bmjrPTlm6_2sgVt7hMZOPfL2M
     */
    @PostMapping("/jsapi/create")
    public Map<String, Object> createJsapiOrder(        // 商户订单号（前端生成，需唯一）
                                                        @RequestParam String payName,        // 商品描述（如“会员充值”）
                                                        @RequestParam BigDecimal price,      // 支付金额（元，如99.00）
                                                        @RequestParam String openid) {       // 小程序用户openid（前端通过wx.login获取）


        Map<String, Object> result = new HashMap<>(2);
        OrderRecordCreateCmd cmd = new OrderRecordCreateCmd();
        cmd.setUserId(StpUtil.getLoginIdAsString());
        cmd.setOpenId(openid);
        cmd.setType(payName);
        cmd.setTotalAmount(price);
        cmd.setCreateTime(LocalDateTime.now());

        SingleResponse<OrderRecordVO> response = orderRecordService.create(cmd);
        if (!response.isSuccess()) {
            result.put("success", false);
            result.put("message", "下单失败"); // 错误信息返回前端提示用户
        }

        String orderId = response.getData().getId();

        try {
            // 调用服务获取调起支付的参数
            PrepayWithRequestPaymentResponse payResponse = wechatPayService.createJsapiPayOrder(
                    orderId, payName, price, openid);

            // 构建前端需要的参数（严格对应微信小程序wx.requestPayment的要求）
            Map<String, String> payParams = new HashMap<>(6);
            payParams.put("appId", payResponse.getAppId());         // 小程序appid
            payParams.put("timeStamp", payResponse.getTimeStamp()); // 时间戳（秒）
            payParams.put("nonceStr", payResponse.getNonceStr());   // 随机字符串
            payParams.put("package", payResponse.getPackageVal());  // 关键：prepay_id=xxx（源码中已封装）
            payParams.put("signType", payResponse.getSignType());   // 签名类型（RSA）
            payParams.put("paySign", payResponse.getPaySign());     // 签名

            result.put("success", true);
            result.put("data", payParams); // 前端用data中的参数调起支付
            result.put("orderId", orderId);

        } catch (Exception e) {
            log.error("创建支付订单失败（订单号：{}）", orderId, e);
            result.put("success", false);
            result.put("message", e.getMessage()); // 错误信息返回前端提示用户
        }
        return result;
    }

    /**
     * 2. 微信支付结果通知回调（微信服务器主动调用）
     * 注意：地址必须与wx.pay.notify-url一致，且公网可访问
     */
    @SaIgnore
    @PostMapping("/notify")
    public String payNotify(
            @RequestBody String notifyData,                          // 通知内容（JSON）
            @RequestHeader("Wechatpay-Serial") String serial,       // 微信支付证书序列号
            @RequestHeader("Wechatpay-Signature") String signature, // 签名
            @RequestHeader("Wechatpay-Nonce") String nonce,         // 随机字符串
            @RequestHeader("Wechatpay-Timestamp") String timestamp) {// 时间戳

        log.info("收到微信支付通知：内容={}", notifyData);
        // 调用服务处理通知，返回微信要求的XML响应
        return wechatPayService.handlePayNotify(notifyData, serial, signature, nonce, timestamp);
    }

    /**
     * 3. 查询订单支付状态（前端支付后主动查询，防止回调延迟）
     * 请求示例：GET /api/pay/wx/query?orderId=PAY20240501001
     */
    @GetMapping("/query")
    public Map<String, Object> queryOrder(@RequestParam String orderId) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            Transaction transaction = wechatPayService.queryOrderByOutTradeNo(orderId);
            // 构建返回给前端的订单状态信息
            Map<String, Object> orderInfo = new HashMap<>(4);
            orderInfo.put("orderId", orderId);
            orderInfo.put("payStatus", transaction.getTradeState()); // 支付状态（SUCCESS/NOT_PAY/CLOSED）
            orderInfo.put("payTime", transaction.getSuccessTime());  // 支付时间（SUCCESS时存在）
            orderInfo.put("tradeNo", transaction.getTransactionId());// 微信订单号（SUCCESS时存在）

            result.put("success", true);
            result.put("data", orderInfo);

        } catch (Exception e) {
            log.error("查询订单状态失败（订单号：{}）", orderId, e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }
        return result;
    }

    /**
     * 4. 关闭未支付订单（前端用户取消支付时调用）
     * 请求示例：POST /api/pay/wx/cancel?orderId=PAY20240501001
     */
    @PostMapping("/cancel")
    public Map<String, Object> cancelOrder(@RequestParam String orderId) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            wechatPayService.closeOrder(orderId);
            result.put("success", true);
            result.put("message", "订单已取消");

        } catch (Exception e) {
            log.error("取消订单失败（订单号：{}）", orderId, e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }
        return result;
    }
}